package com.atguigu.product.service.impl;

import com.atguigu.common.constants.ProductConstant;
import com.atguigu.product.dao.AttrAttrgroupRelationDao;
import com.atguigu.product.dao.AttrDao;
import com.atguigu.product.dao.AttrGroupDao;
import com.atguigu.product.entity.AttrAttrgroupRelationEntity;
import com.atguigu.product.entity.AttrEntity;
import com.atguigu.product.entity.AttrGroupEntity;
import com.atguigu.product.entity.CategoryEntity;
import com.atguigu.product.service.AttrAttrgroupRelationService;
import com.atguigu.product.service.AttrGroupService;
import com.atguigu.product.service.CategoryService;
import com.atguigu.product.vo.AttrGroupRelationVo;
import com.atguigu.product.vo.AttrRespVo;
import com.atguigu.product.vo.AttrVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.product.service.AttrService;
import org.springframework.transaction.annotation.Transactional;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Autowired
    AttrAttrgroupRelationService attrAttrgroupRelationService;

    @Autowired
    CategoryService categoryService;

    @Autowired
    AttrGroupService attrGroupService;

    @Autowired
    AttrAttrgroupRelationDao attrAttrgroupRelationDao;

    @Autowired
    AttrGroupDao attrGroupDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }
    @Transactional
    @Override
    public void saveAttr(AttrVo attrVo) {

        AttrEntity attrEntity = new AttrEntity();
        //保存attrEntity
        //利用attr的属性给attrEntity的属性赋值，前提是他们俩的属性名一致
        BeanUtils.copyProperties(attrVo, attrEntity);
        this.save(attrEntity);

        //保存关联
        if (attrVo.getAttrType().equals(ProductConstant.AttrTypeEnum.ATTR_TYPE_BASE.getCode()) && attrVo.getAttrGroupId()!=null ) {

            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
            attrAttrgroupRelationEntity.setAttrId(attrEntity.getAttrId());
            attrAttrgroupRelationEntity.setAttrGroupId(attrVo.getAttrGroupId());
            attrAttrgroupRelationService.save(attrAttrgroupRelationEntity);

        }


    }

    @Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId, String attrType) {

        LambdaQueryWrapper<AttrEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AttrEntity::getAttrType, "base".equalsIgnoreCase(attrType)
                ? 1
                : 0);


        if (catelogId!=0) {
            queryWrapper.eq(AttrEntity::getCatelogId, catelogId);
        }

        String key = (String) params.get("key");
        if (StringUtils.isNotEmpty(key)) {
            queryWrapper.and((obj)->{
                obj.eq(AttrEntity::getAttrId, key)
                        .or()
                        .like(AttrEntity::getAttrName, key);
            });
        }

        IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params),
                queryWrapper);
        PageUtils pageUtils = new PageUtils(page);

        //查找分类名和分组名, 封装到Vo
        List<AttrEntity> records = page.getRecords();
        List<AttrRespVo> respVos = records.stream().map((attrEntity) -> {

            AttrRespVo attrRespVo = new AttrRespVo();
            BeanUtils.copyProperties(attrEntity, attrRespVo);

            //查询类名和分组名
            //1. 根据分类Id查找category表的分类名

            CategoryEntity categoryEntity = categoryService.getOne(new LambdaQueryWrapper<CategoryEntity>()
                    .eq(CategoryEntity::getCatId, attrEntity.getCatelogId())
            );

            if (Objects.nonNull(categoryEntity)) {
                attrRespVo.setCatelogName(categoryEntity.getName());
            }


            //注意: 销售属性没有分组！！！
            if ("base".equalsIgnoreCase(attrType)) {
                //2. 根据属性id去属性分组关联表中查找属性分组id
                AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = attrAttrgroupRelationService.getOne(
                        new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                                .eq(AttrAttrgroupRelationEntity::getAttrId, attrEntity.getAttrId())
                );

                if (Objects.nonNull(attrAttrgroupRelationEntity) &&Objects.nonNull(attrAttrgroupRelationEntity.getAttrGroupId()) ) {

                    //2.1 根据属性分组id去属性分组表查找属性分组名
                    AttrGroupEntity attrGroupEntity = attrGroupService.getOne(
                            new LambdaQueryWrapper<AttrGroupEntity>()
                                    .eq(AttrGroupEntity::getAttrGroupId,
                                            attrAttrgroupRelationEntity.getAttrGroupId())
                    );
                    attrRespVo.setGroupName(attrGroupEntity.getAttrGroupName());
                }

            }

            return attrRespVo;
        }).collect(Collectors.toList());

         pageUtils.setList(respVos);

         return pageUtils;


    }


    @Override
    public AttrRespVo getAttrInfo(Long attrId) {

        //1. 根据属性id，到属性分组关联表里查询属性分组id
        AttrRespVo attrRespVo = new AttrRespVo();
        AttrEntity attrEntity = this.getById(attrId);

        BeanUtils.copyProperties(attrEntity, attrRespVo);

        //查询分组
        if (attrRespVo.getAttrType().equals(ProductConstant.AttrTypeEnum.ATTR_TYPE_BASE.getCode())) {
            AttrAttrgroupRelationEntity attrAttrgroupRelation = attrAttrgroupRelationService.getOne(
                    new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                            .eq(AttrAttrgroupRelationEntity::getAttrId, attrId)
            );

            //2. 从AttrAttrgroupRelationEntity中获取分组id, 并封装到Vo中
            if (Objects.nonNull(attrAttrgroupRelation)) {
                attrRespVo.setAttrGroupId(attrAttrgroupRelation.getAttrGroupId());
            }
        }



        //查询分类
        //3. 根据属性分组id找到三级分类菜单的catelogPath, 并封装到vo中
        Long[] catelogPath = categoryService.findCatelogPath(attrEntity.getCatelogId());
        attrRespVo.setCatelogPath(catelogPath);

        return attrRespVo;
    }


    /**
     * 更新属性表和属性分组关联表
     * @param attrVo
     */
    @Transactional
    @Override
    public void updateAttr(AttrVo attrVo) {

        //1. 更新属性表
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attrVo, attrEntity);
        this.updateById(attrEntity);

        if(attrEntity.getAttrType().equals(ProductConstant.AttrTypeEnum.ATTR_TYPE_BASE.getCode())){

            //2. 更新属性分组关联表
            AttrAttrgroupRelationEntity attrAttrgroupRelation = new AttrAttrgroupRelationEntity();
            attrAttrgroupRelation.setAttrId(attrVo.getAttrId());
            attrAttrgroupRelation.setAttrGroupId(attrVo.getAttrGroupId());



            //有可能因为页面不显示分组，说明属性id在属性分组关联表中没有关联的属性id
            //判断, 根据属性id去属性分组关联表中查对应的记录数，如果记录数=0说明没有关联的属性id,需要新增，否则修改
            int count = attrAttrgroupRelationService.count(
                    new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                            .eq(AttrAttrgroupRelationEntity::getAttrId, attrVo.getAttrId())
            );
            if (count>0) {
                attrAttrgroupRelationService.update(attrAttrgroupRelation,
                        new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                                .eq(AttrAttrgroupRelationEntity::getAttrId, attrVo.getAttrId())
                );
            }else{
                attrAttrgroupRelationService.save(attrAttrgroupRelation);
            }

        }




    }

    /**
     * 获取属性分组关联的所有属性
     * @param attrgroupId
     * @return
     */
    @Override
    public List<AttrEntity> getRelationAttr(Long attrgroupId) {

        //1. 根据属性分组id查询  属性属性分组关联表的属性id
        List<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntities = attrAttrgroupRelationService.list(
                new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                        .eq(attrgroupId!=null, AttrAttrgroupRelationEntity::getAttrGroupId, attrgroupId)
        );

        if (attrAttrgroupRelationEntities==null || attrAttrgroupRelationEntities.size()==0) {
            return null;
        }

        //2. 根据属性id, 查到相应的数据并返回
        List<Long> attrIds = attrAttrgroupRelationEntities.stream().map((AttrAttrgroupRelationEntity) -> {

             return AttrAttrgroupRelationEntity.getAttrId();

        }).collect(Collectors.toList());

        if (attrIds==null || attrIds.size()==0){
            return null;
        }


        List<AttrEntity> attrEntities = this.listByIds(attrIds);

        return attrEntities;
    }

    @Override
    public void deleteRelation(AttrGroupRelationVo[] vos) {

        List<AttrGroupRelationVo> relationVos = Arrays.asList(vos);

        //构建由Vo组成的关联表的一个集合
        List<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntities = relationVos.stream().map((vo) -> {

            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();

            BeanUtils.copyProperties(vo, attrAttrgroupRelationEntity);
            return attrAttrgroupRelationEntity;
        }).collect(Collectors.toList());

        //批量删除分组和属性的关联
        attrAttrgroupRelationDao.deleteBatchRelation(attrAttrgroupRelationEntities);


    }

    /**
     * 获取属性分组没有关联的其他属性
     * @param attrgroupId
     * @param params
     * @return
     */
    @Override
    public PageUtils getNoAttrRelation(Long attrgroupId, Map<String, Object> params) {
        /*//获取属性分组没有关联的其他属性


        //1. 当前分组只能关联自己所属分类的所有属性
        //1)、首先在属性分组表中查到所属的分类
        //2)、 然后根据上一步分类的id找到相应的所有属性
        AttrGroupEntity attrGroup = attrGroupService.getById(attrgroupId);
        Long catelogId = attrGroup.getCatelogId();

        //2. 当前分组只能关联别的分组没有关联过的属性
        //1、) 在属性分组表中根据分类id找到对应的分类
        List<AttrGroupEntity> attrGroupEntities = attrGroupService.list(new LambdaQueryWrapper<AttrGroupEntity>().eq(AttrGroupEntity::getCatelogId, catelogId));
        //获取属性分组id列表集合
        List<Long> attrGroupIds = attrGroupEntities.stream().map((item) -> {
            Long attrGroupId = item.getAttrGroupId();

            return attrGroupId;
        }).collect(Collectors.toList());

        //关联的属性
        List<AttrAttrgroupRelationEntity> attrAttrgroupRelation = attrAttrgroupRelationService.list(
                new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                        .in(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupIds
               ));

        //从当前的分类中移除这些属性
        List<Long> attrIds = attrAttrgroupRelation.stream().map((item) -> {
            return item.getAttrId();
        }).collect(Collectors.toList());

        LambdaQueryWrapper<AttrEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AttrEntity::getCatelogId, catelogId)
                .eq(AttrEntity::getAttrType, ProductConstant.AttrTypeEnum.ATTR_TYPE_BASE);

        if (attrIds != null && attrIds.size() > 0) {
            lambdaQueryWrapper.notIn(AttrEntity::getAttrId, attrIds);
        }
        //模糊查询
        String key = (String) params.get("key");

        if (!StringUtils.isEmpty(key)) {
            lambdaQueryWrapper.and((item)->{
                item.eq(AttrEntity::getAttrId, key)
                        .or()
                        .like(AttrEntity::getAttrName, key);
            });
        }

        IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params), lambdaQueryWrapper);

        return new PageUtils(page);*/

        //1、当前分组只能关联自己所属分类里面的所有属性
        //先查询出当前分组所属的分类
        AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupId);
        Long catelogId = attrGroupEntity.getCatelogId();
        //2、当前分组只能关联别的分组没有引用的属性
        //2.1当前分类下的所有分组
        List<AttrGroupEntity> attrGroupEntities = attrGroupDao.selectList(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));
        List<Long> attrGroupIds = attrGroupEntities.stream().map(attrGroupEntity1 -> {
            return attrGroupEntity1.getAttrGroupId();
        }).collect(Collectors.toList());
        //2.2这些分组关联的属性
        List<AttrAttrgroupRelationEntity> relationEntities = attrAttrgroupRelationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", attrGroupIds));
        List<Long> attrIds = relationEntities.stream().map((relationEntity) -> {
            return relationEntity.getAttrId();
        }).collect(Collectors.toList());
        // 从当前分类的所有属性中移除这些属性
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<AttrEntity>().eq("catelog_id", catelogId).eq("attr_type", ProductConstant.AttrTypeEnum.ATTR_TYPE_BASE.getCode());
        if (attrIds != null && attrIds.size() > 0){
            wrapper.notIn("attr_id", attrIds);
        }
        //模糊查询
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)){
            wrapper.and((w)->{
                w.eq("attr_id", key).or().like("attr_name", key);
            });
        }
        IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params), wrapper);

        return new PageUtils(page);
    }

    @Override
    public List<Long> selectSearchAttrs(List<Long> attrIds) {

            return this.baseMapper.selectSearchAttrs(attrIds);
    }


}